package sicnu.cs.ich.es.rest;

import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import sicnu.cs.ich.api.common.ResultInfo;
import sicnu.cs.ich.common.util.ResultInfoUtil;
import sicnu.cs.ich.es.config.ElasticSearchIndex;
import sicnu.cs.ich.es.service.ElasticService;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author 沈洋 邮箱:1845973183@qq.com
 * @create 2021/11/29-20:52
 **/
@RestController
@Slf4j
@RequestMapping("/auth/es")
@RequiredArgsConstructor
public class ElasticSearchResource {
    private final ElasticService elasticService;

    @ApiOperation("根据非遗名称进行搜索")
    @GetMapping("/searchIch")
    public ResultInfo<List<Map<String,Object>>> searchIch(@RequestParam String key){
        // 限制查询字符串长度，避免es查询压力
        if (key.length()>20){
            key = key.trim().substring(0,21);
        }
        log.info("查询数据:"+key);
        // 构建搜索条件
        var sourceBuilder = new SearchSourceBuilder();
        // 构建查询条件(精确匹配)
        var query = QueryBuilders.boolQuery();
        query.must(QueryBuilders.boolQuery().must(QueryBuilders.matchPhraseQuery("name",key)));
        sourceBuilder.query(query);
        // 过滤返回字段
        sourceBuilder.fetchSource(new String[]{"name","id"},null);
        // 只取前10条
        sourceBuilder.from(0).size(10);
        // 设置高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name");
        highlightBuilder.requireFieldMatch(true);
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");

        sourceBuilder.highlighter(highlightBuilder);
        var response = elasticService.searchDocument(ElasticSearchIndex.ICH,sourceBuilder);
        var hits = response.getHits();
        var list = new ArrayList<Map<String,Object>>();
        for (SearchHit hit : hits) {
            var highlights = hit.getHighlightFields();
            var fragments = highlights.get("name").fragments();
            StringBuilder text = new StringBuilder();
            for (Text fragment : fragments) {
                text.append(fragment.toString());
            }
            var source = hit.getSourceAsMap();
            source.put("highlight_name",text.toString());
            list.add(source);
        }
        return ResultInfoUtil.buildSuccess(list);
    }
}
